fn main() {
    {
        // There is no -> so it's not returning anything.
        // If number was not Copy type, it would take it
        // and we couldn't use it again.
        fn prints_number(number: i32) {
            println!("{}", number);
        }

        let my_number = 8;
        // Prints 8. prints_number gets a copy of my_number.
        prints_number(my_number);
        // Prints 8 again. No problem, because my_number is Copy type!
        prints_number(my_number);
    }

    println!();

    {
        fn prints_country(country_name: String) {
            println!("{}", country_name);
        }

        let country = String::from("Kiribati");
        // Make a clone and give it to the function. Only the clone goes in,
        // and country is still alive.
        prints_country(country.clone());
        prints_country(country);
    }

    println!();

    {
        // Takes ownership of a String.
        fn num_of_words(input: String) {
            // Splits to count the number of words.
            println!("It's {} words long.", input.split_whitespace().count());
        }

        let mut my_string = String::new();
        for _ in 0..50 {
            // Push the words on.
            my_string.push_str("Here are some more words ");
            // Gives it a clone every time.
            num_of_words(my_string.clone());
        }
    }

    println!();

    {
        // Takes ownership of a String.
        fn num_of_words(input: &str) {
            // Splits to count the number of words.
            println!("It's {} words long.", input.split_whitespace().count());
        }

        // Instead of 50 clones, it's zero.
        let mut my_string = String::new();
        for _ in 0..50 {
            // Push the words on.
            my_string.push_str("Here are some more words ");
            num_of_words(&my_string);
        }
    }

    println!();

    {
        fn loop_then_return(mut counter: i32) -> i32 {
            loop {
                counter += 1;
                if counter % 50 == 0 {
                    break;
                }
            }

            counter
        }

        let my_number;

        {
            // Pretend we need to have this code block.
            let number = {
                // Pretend there is code here to make a number.
                // Lots of code, and finally:
                57
            };

            my_number = loop_then_return(number);
        }

        println!("{}", my_number);
    }

    println!();

    {
        let my_number;
        {
            my_number = 100;
        }
        println!("{}", my_number);
    }

    println!();

    {
        let my_number = { 100 };
        println!("{}", my_number);
    }
}
